package main

import (
	"fmt"
	"reflect"
)

// 使用interface限定参数类型，动态调用struct中的方法、方法

type A1 interface {
	Show1(name string)
}

type B1 struct {
	Name1   string
	Age1    uint
	Sex1    string
	IsOver1 bool
}

func (b1 B1) Show1(name string) {
	fmt.Println(reflect.TypeOf(b1), name)
}

func (b1 B1) Run1() {
	fmt.Print("b1->Run1()")
}

type C1 struct {
}

func (c1 C1) Show1(name string) {
	fmt.Println(reflect.TypeOf(c1))
}

type D1 struct {
}

func (d1 D1) Run1(name string) {
	fmt.Println(reflect.TypeOf(d1))
}

func printShow(a A1, menthod string, args ...interface{}) {
	inputs := make([]reflect.Value, len(args))
	for i, _ := range args {
		inputs[i] = reflect.ValueOf(args[i])
	}
	// 动态调用struct中的方法
	reflect.ValueOf(a).MethodByName(menthod).Call(inputs)

	// 动态调用struct中的属性
	fmt.Println("所有属性值", reflect.ValueOf(a).Elem())
	fmt.Println("指定属性值", reflect.ValueOf(a).Elem().FieldByName("IsOver1"))
}

func main() {
	// printShow(&B1{}, "Show1", "b->show1()")
	printShow(&B1{}, "Run1")

	// 调用一个未实现接口的方法
	// printShow(&D1{}, "Run1")
}
